package model

import (
	"errors"
	"fmt"
	"project/schedule/util"
	"strconv"
)

func AllocateProposed(g *General, p *Project) error {
	allocation := &Allocation{}
	proposedStartDate := p.ProposedStartDate
	proposedEndDate := util.WorkDayIndex2Value[util.WorkDayValue2Index[proposedStartDate]+p.ProposedDay-1]
	projectScale := util.Scale(p.ProposedDay, g.ProjectScale)
	// 先分配本部门
	for employee, employeeInfo := range g.Staff {
		if employeeInfo.Department != p.Department {
			continue
		}
		if util.CrossOverMulti(proposedStartDate, proposedEndDate, employeeInfo.Vacation) {
			continue
		}
		if util.CrossOverMulti(proposedStartDate, proposedEndDate, employeeInfo.WorkRegion) {
			continue
		}
		Allocating(g, p, allocation, employeeInfo, employee, projectScale, proposedStartDate, proposedEndDate)
	}
	// 后分配其他部门
	for employee, employeeInfo := range g.Staff {
		if employeeInfo.Department == p.Department {
			continue
		}
		if util.CrossOverMulti(proposedStartDate, proposedEndDate, employeeInfo.Vacation) {
			continue
		}
		if util.CrossOverMulti(proposedStartDate, proposedEndDate, employeeInfo.WorkRegion) {
			continue
		}
		if !employeeInfo.LendOut {
			continue
		}
		Allocating(g, p, allocation, employeeInfo, employee, projectScale, proposedStartDate, proposedEndDate)
	}
	if allocation.GroupJudge == "" || allocation.GroupLeader == "" {
		return errors.New(fmt.Sprintf("`%s`暂未分配成功", p.Name))
	}
	outPack := g.Project[p.Name].OutPack
	x, _ := strconv.ParseInt(proposedStartDate[4:6], 10, 64)
	groupLeaderJudgeSlice := make([]string, 0)
	groupLeaderJudgeSlice = append(groupLeaderJudgeSlice, allocation.GroupJudge)
	groupLeaderJudgeSlice = append(groupLeaderJudgeSlice, allocation.GroupLeader)
	different := len(util.Duplicate(groupLeaderJudgeSlice))
	if outPack != 0 && int(x) >= outPack {
		lack := p.ProposedPerson - different
		for i := 0; i < lack; i++ {
			allocation.GroupMember = append(allocation.GroupMember, "wb")
		}
	} else {
		lack := p.ProposedPerson - len(allocation.GroupMember) - different
		for i := 0; i < lack; i++ {
			allocation.GroupMember = append(allocation.GroupMember, "wb")
		}
	}

	allocateDetail := make(map[string]map[string]string)

	// 若组长和主审为同一个人, 则用主审来更新
	if allocation.GroupLeader == allocation.GroupJudge {
		before, after := util.AuditDay(p.ProposedDay, "主审", g.AuditRule)
		startDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedStartDate]-before]
		endDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedEndDate]+after]
		allocateDetail[allocation.GroupJudge] = make(map[string]string)
		allocateDetail[allocation.GroupJudge]["startDate"] = startDate
		allocateDetail[allocation.GroupJudge]["endDate"] = endDate
		g.Staff[allocation.GroupJudge].WorkRegion = append(g.Staff[allocation.GroupJudge].WorkRegion,
			allocateDetail[allocation.GroupJudge])
	} else {
		// 更新组长的workRegion
		before, after := util.AuditDay(p.ProposedDay, "组长", g.AuditRule)
		startDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedStartDate]-before]
		endDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedEndDate]+after]
		allocateDetail[allocation.GroupLeader] = make(map[string]string)
		allocateDetail[allocation.GroupLeader]["startDate"] = startDate
		allocateDetail[allocation.GroupLeader]["endDate"] = endDate
		g.Staff[allocation.GroupLeader].WorkRegion = append(g.Staff[allocation.GroupLeader].WorkRegion,
			allocateDetail[allocation.GroupLeader])
		// 更新主审的workRegion
		before, after = util.AuditDay(p.ProposedDay, "主审", g.AuditRule)
		startDate = util.AllDayIndex2Value[util.AllDayValue2Index[proposedStartDate]-before]
		endDate = util.AllDayIndex2Value[util.AllDayValue2Index[proposedEndDate]+after]
		allocateDetail[allocation.GroupJudge] = make(map[string]string)
		allocateDetail[allocation.GroupJudge]["startDate"] = startDate
		allocateDetail[allocation.GroupJudge]["endDate"] = endDate
		g.Staff[allocation.GroupJudge].WorkRegion = append(g.Staff[allocation.GroupJudge].WorkRegion,
			allocateDetail[allocation.GroupJudge])
	}

	// 更新组员的workRegion
	before, after := util.AuditDay(p.ProposedDay, "组员", g.AuditRule)
	startDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedStartDate]-before]
	endDate := util.AllDayIndex2Value[util.AllDayValue2Index[proposedEndDate]+after]
	for _, staff := range allocation.GroupMember {
		if staff == "wb" {
			continue
		}
		allocateDetail[staff] = make(map[string]string)
		allocateDetail[staff]["startDate"] = startDate
		allocateDetail[staff]["endDate"] = endDate
		g.Staff[staff].WorkRegion = append(g.Staff[staff].WorkRegion, allocateDetail[staff])
	}

	// 补全信息
	allocation.DepartmentProposedStartDate = g.Department[p.Department].ProposedStartDate
	allocation.ProjectProposedDay = p.ProposedDay
	allocation.ProjectProposedPerson = p.ProposedPerson
	allocation.ProjectProposedStartDate = proposedStartDate
	allocation.ProjectAllocatedStartDate = proposedStartDate
	allocation.ProjectAllocatedEndDate = proposedEndDate
	allocation.ProjectDepartment = p.Department
	allocation.ProjectAllocatedDetail = allocateDetail
	g.Allocation[p.Name] = allocation
	return nil
}
